#include "pch.hpp"
#include "BasicCodeHighlighter.hpp"

using namespace Engine;
using namespace Engine::Edit;




BasicCodeHighlighter::BasicCodeHighlighter(QTextDocument *parent)
	: QSyntaxHighlighter(parent)
	, m_font("Calibri")
{
	m_font.setPointSize(10);
	m_font.setFixedPitch(true);
	m_font.setKerning(false);
	m_font.setItalic(false);
	m_font.setOverline(false);
	m_font.setUnderline(false);
	m_font.setWeight(QFont::Normal);

	Rule rule;
	QTextCharFormat fmt;

	rule.pattern = QRegExp("\"[^\n\"]*\"?");
	rule.format = basicFormat(StringConstant);
	add(rule);

	rule.pattern = QRegExp("//[^\n]*");
	rule.format = basicFormat(Comment);
	add(rule);

	m_commentStartExpression = QRegExp("/\\*");
	m_commentEndExpression = QRegExp("\\*/");

	m_defaultFormat = basicFormat(Default);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

BasicCodeHighlighter::~BasicCodeHighlighter()
{}
///////////////////////////////////////////////////////////////////////////////////////////////////




QFont BasicCodeHighlighter::font() const
{
	return m_font;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void BasicCodeHighlighter::highlightBlock(const QString &text)
{
	// We will first set the default format for the entire text.
	// This ensures that when somone copies text into the document,
	// it won't have the original formatting
	//setFormat(0, text.size(), m_defaultFormat);

	foreach(const auto& rule, m_rules)
	{
		QRegExp expression(rule.pattern);
		int index = text.indexOf(expression);
		while (index >= 0)
		{
			int length = expression.matchedLength();
			setFormat(index, length, rule.format);
			index = text.indexOf(expression, index + length);
		}
	}

	setCurrentBlockState(0);

	int startIndex = 0;
	if(previousBlockState() != 1)
		startIndex = text.indexOf(m_commentStartExpression);

	while(startIndex >= 0)
	{
		int endIndex = text.indexOf(m_commentEndExpression, startIndex);
		int commentLength;

		if(endIndex == -1)
		{
			setCurrentBlockState(1);
			commentLength = text.length() - startIndex;
		}
		else
		{
			commentLength = endIndex - startIndex + m_commentEndExpression.matchedLength();
		}

		setFormat(startIndex, commentLength, m_commentFormat);
		startIndex = text.indexOf(m_commentStartExpression, startIndex + commentLength);
	}
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void BasicCodeHighlighter::add(const Rule& rule)
{
	m_rules << rule;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

QTextCharFormat BasicCodeHighlighter::basicFormat(BasicType type) const
{
	QTextCharFormat fmt;
	fmt.setFont(m_font);

	switch(type)
	{
	case Comment:
		fmt.setForeground(QColor(0, 128, 0));
		fmt.setBackground(QColor(242, 254, 237));
		break;

	case StringConstant:
		fmt.setForeground(QColor(128, 0, 0));
		break;

	case Default:
		fmt.setForeground(QColor(0, 0, 0));
		break;

	default:
		throw invalid_value_exception(type);
	}

	return fmt;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
